#!/bin/bash

# Copyright © 2016-2017 Simon McVittie
# Copyright © 2017-2018 Collabora Ltd.
#
# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

set -e
set -u
set -o pipefail

me="$(basename "$0")"
debug=

usage () {
    local status="${1-2}"

    if [ "$status" -ne 0 ]; then
        exec >&2
    fi

    echo "$me: Usage"
    echo "    $me SYSROOT"
    echo
    echo "Run this script as root."
    exit "$status"
}

getopt_temp="$(getopt -o '' --long \
    'help,debug' \
    -n "$me" -- "$@")"

eval set -- "$getopt_temp"
unset getopt_temp

while [ "$#" -gt 0 ]; do
    case "$1" in
        (--debug)
            debug=yes
            shift
            ;;

        (--help)
            usage 0
            # not reached
            ;;

        (--)
            shift
            break
            ;;

       (-*)
            echo "$me: unknown option: $1" >&2
            usage 2
            # not reached
            ;;

        (*)
            break
            ;;
    esac
done

if [ "x$(id -u)" != x0 ] || [ "$#" -ne 1 ]; then
    usage 2
    # not reached
fi

if [ -n "$debug" ]; then
    set -x
fi

sysroot="$1"
cd "$sysroot"

in_chroot () {
    chroot "$sysroot" "$@"
}

export DEBIAN_FRONTEND=noninteractive

exec 3>"$sysroot/usr/manifest.dpkg"

printf '#Package[:Architecture]\t#Version\t#Source\t#Installed-Size\n' >&3

# ${} escapes here are for dpkg-query, not sh
# shellcheck disable=SC2016
dpkg_version="$(in_chroot dpkg-query -W -f '${Version}' dpkg)"

if in_chroot dpkg --compare-versions "$dpkg_version" ge 1.16.2; then
    # shellcheck disable=SC2016
    in_chroot dpkg-query -W -f \
        '${binary:Package}\t${Version}\t${Source}\t${Installed-Size}\n' \
        | LC_ALL=C sort -u >&3
    # shellcheck disable=SC2016
    in_chroot dpkg-query -W -f '${binary:Package}\n' \
        | LC_ALL=C sort -u \
        | in_chroot xargs -d '\n' dpkg-query -s \
        | gzip -9nc \
        > "$sysroot/usr/manifest.deb822.gz"
else
    # shellcheck disable=SC2016
    in_chroot dpkg-query -W -f \
        '${Package}:${Architecture}\t${Version}\t${Source}\t${Installed-Size}\n' \
        | LC_ALL=C sort -u >&3
fi

exec 3>"$sysroot/usr/manifest.dpkg.built-using"

printf '#Built-Binary\t#Built-Using-Source\t#Built-Using-Version\n' >&3

# shellcheck disable=SC2016
in_chroot dpkg-query -W -f '${Package}\t${Built-Using}\n' | perl -ne '
chomp;
die "Unable to parse dpkg-query output: $_\n" unless /^(\S+)\t(.*)$/;
next unless $2;
my $binary = $1;
my @using = split /,/, $2;
next unless @using;
foreach my $using (@using) {
    $using =~ s/ //g;
    die "Unable to parse Built-Using: $using\n"
        unless $using =~ /^(\S+)\(=(\S+)\)$/;
    print "$binary\t$1\t$2\n";
}
' | LC_ALL=C sort -u >&3

# vim:set sw=4 sts=4 et:
